<template>
  <div class="p-4">
    <BasicModal v-model:visible="addVisibleTree" title="编辑菜单权限" @ok="onSubmit">
      <Form
        class="form_box"
        :model="formState"
        ref="formRef"
        :rules="rules"
        :label-col="{ span: 6 }"
        :wrapper-col="{ span: 16 }"
      >
        <FormItem label="" name="menuIds">
          <BasicTree
            v-model:value="formState.menuIds"
            style="width: 100%"
            :tree-data="routersAll"
            checkable
            ref="changeTree"
            allow-clear
            search-placeholder="Please select"
          />
        </FormItem>
      </Form>
    </BasicModal>
  </div>
</template>
<script lang="ts" setup>
  import { ref, onMounted, reactive } from 'vue';
  import {
    Form,
    Input,
    FormItem,
  } from 'ant-design-vue';
  import {
    getAllroutes,
    setCompanyRoutes,
    getCompanyRoutes,
    getPeoRoutes,
    setPeoRoutes,
    getMyselfRoutes,
  } from '/@/api/api';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { BasicModal } from '/@/components/Modal';
  import { BasicTree } from '/@/components/Tree/index';

  type TreeNode = {
    id: string;
    comment: string;
    children?: TreeNode[];
  };

  type TransformedTreeNode = {
    value: string;
    title: string;
    key: string;
    children?: TransformedTreeNode[];
  };
  const addVisibleTree = ref(false);
  const reqId = ref('');
  const kind = ref('');
  const peoId = ref('');
  const init = (data) => {
    console.log(routersAll.value);
    addVisibleTree.value = true;
    kind.value = data.kind;
    peoId.value = data.peoId;
    reqId.value = data.comid;
    if (kind.value == 'branchOffice') {
      getNowPeoMenu();
      getMyselfRoutes().then((res) => {
        const transformedData: TransformedTreeNode[] = transformTree(res);
        routersAll.value = transformedData;
      });
    } else {
      menuPermissions();
    }
    if (kind.value == 'headOffice') {
      getNowPeoMenu();
    }
  };

  const transformNode = (node: TreeNode, parentTitle: string = ''): TransformedTreeNode => {
    const newTitle = parentTitle ? `${parentTitle}-${node.comment}` : node.comment;

    const transformedNode: TransformedTreeNode = {
      value: node.id,
      title: newTitle,
      key: node.id,
      children: node.children ? node.children.map(child => transformNode(child, newTitle)) : undefined,
    };
    return transformedNode;
  };

  const transformTree = (tree: TreeNode[]): TransformedTreeNode[] => {
    return tree.map(node => transformNode(node));
  };

  const { createMessage } = useMessage();
  // 设置菜单权限
  const popStatic = ref(1);
  const getAllChildrenIds = (nodes: TreeNode[]): string[] => {
    const ids: string[] = [];
    const traverse = (nodes: TreeNode[]) => {
      for (const node of nodes) {
        if (node.children) {
          ids.push(...node.children.map(child => child.id));
          traverse(node.children);
        }
      }
    };
    traverse(nodes);
    return ids;
  };
  // 获取当前这个用户已经拥有的权限
  const getNowPeoMenu = () => {
    getPeoRoutes({
      staffId: peoId.value,
    }).then((res) => {
      console.log(res);
      if (res && res.length > 0) {
        formState.menuIds = getAllChildrenIds(res);
      } else {
        formState.menuIds = [];
      }
    });
  };
  // 选择完弹窗的时候请求一下获取当前的权限
  const menuPermissions = () => {
    getCompanyRoutes({
      companyId: reqId.value,
    }).then((res) => {
      if (kind.value == 'headOffice') {
        // 总公司给职工中账号设置权限需要从公司账号里面获取权限进行选择
        const transformedData: TransformedTreeNode[] = transformTree(res);
        routersAll.value = transformedData;
      } else {
        // 公司权限设置-获取公司的权限列表
        if (res && res.length > 0) {
          formState.menuIds = getAllChildrenIds(res);
        } else {
          formState.menuIds = [];
        }
      }
    });
  };
  const formRef = ref();
  const formState: any = reactive({
    menuIds: [],
  });
  const rules = {
    menuIds: [{ required: true, message: '请选择菜单权限' }],
  };
  const changeTree = ref();
  const findParentValues = (tree: TransformedTreeNode[], selectedValues: string[]): string[] => {
    const parentMap = new Map<string, string | null>();

    const constructParentMap = (nodes: TransformedTreeNode[], parentId: string | null) => {
      for (const node of nodes) {
        parentMap.set(node.value, parentId);
        if (node.children && node.children.length > 0) {
          constructParentMap(node.children, node.value);
        }
      }
    };

    const getParentValues = (values: string[]): string[] => {
      const result = new Set<string>();
      for (const value of values) {
        result.add(value);
        let parentValue = parentMap.get(value);
        while (parentValue) {
          result.add(parentValue);
          parentValue = parentMap.get(parentValue);
        }
      }
      return Array.from(result);
    };

    constructParentMap(tree, null);
    return getParentValues(selectedValues);
  };
  const onSubmit = () => {
    formRef.value
      .validate()
      .then(() => {
        console.log(formState.menuIds);
        let menuIdsArr2 = changeTree.value.getCheckedKeys();
        if (kind.value == 'headOffice' || kind.value == 'branchOffice') {
          setPeoRoutes({
            staffId: peoId.value,
            menuIds: findParentValues(routersAll.value,menuIdsArr2),
          }).then(() => {
            createMessage.success('添加成功');
            addVisibleTree.value = false;
          });
        } else {
          setCompanyRoutes({
            companyId: reqId.value,
            menuIds: findParentValues(routersAll.value,menuIdsArr2),
          }).then(() => {
            createMessage.success('添加成功');
            addVisibleTree.value = false;
          });
        }
      })
      .catch((error: any) => {
        console.log('error', error);
      });
  };
  const routersAll = ref([]);
  onMounted(() => {
    getAllroutes().then((res) => {
      const transformedData: TransformedTreeNode[] = transformTree(res);
      routersAll.value = transformedData;
      console.log(transformedData);
    });
  });
  defineExpose({
    init,
  });
</script>

<style lang="less" scoped></style>
